package app

import (
	"errors"
	"fmt"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"time"
)

// TInstance 接口报文结构
type TInstanceDocument struct {
	Cmd          string                `json:"cmd"`           //命令字（全部大写），如REG=注册新服务
	MsgId        string                `json:"msg_id"`        //消息ID
	CmdParams    TInstanceCmdParams    `json:"cmd_params"`    //命令参数
	ReturnParams TInstanceReturnParams `json:"return_params"` //返回数据参数
}

// TInstanceReturnParams TInstance的返回数据参数
type TInstanceReturnParams struct {
	Format           string `json:"format"`           //返回数据格式，包括text, json, excel file, csv file
	Protocol         string `json:"protocol"`         //返回时采用的协议，包括http和mqtt
	Mqtt_Host        string `json:"mqtt_host"`        //MQTT服务器地址
	Mqtt_Port        int    `json:"mqtt_port"`        //MQTT服务器端口
	Mqtt_topic_root  string `json:"mqtt_topic_root"`  //MQTT协议根主题
	Mqtt_topic_child string `json:"mqtt_topic_child"` //MQTT协议子主题
	Mqtt_User        string `json:"mqtt_user"`        //MQTT协议用户名
	Mqtt_Pwd         string `json:"mqtt_pwd"`         //MQTT协议密码
}

// TInstanceCmdParams TInstance的命令参数结构
type TInstanceCmdParams struct {
	RowID              int    `json:"row_id"`              //数据库中的行ID
	Uni_Id             string `json:"uni_id"`              //服务接口号
	ServiceName        string `json:"service_name"`        //服务名称
	ServiceDescription string `json:"service_description"` //服务描述
	ServiceType        int    `json:"service_type"`        //服务类型
	Http_Enabled       int    `json:"http_enabled"`        //是否提供http服务
	Http_Host          string `json:"http_host"`           //HTTP服务根URL
	Http_Port          int    `json:"http_port"`           //HTTP服务端口
	Mqtt_Enabled       int    `json:"mqtt_enabled"`        //是否提供Mqtt服务
	Mqtt_Host          string `json:"mqtt_host"`           //MQTT服务器地址
	Mqtt_Port          int    `json:"mqtt_port"`           //MQTT服务器端口
	Mqtt_topic_root    string `json:"mqtt_topic_root"`     //MQTT协议根主题
	Mqtt_Params        string `json:"mqtt_params"`         //MQTT连接参数
}

// TServiceCapability 接口能力结构
type TServiceCapability struct {
	Uni_id      string `json:"uni_id"`      //对应master表的uuid
	Caption     string `json:"caption"`     //能力名称
	Description string `json:"description"` //能力描述
	Protocol    string `json:"protocol"`    //调用协议
	Intf_id     string `json:"intf_id"`     //接口能力编号
	Http_Params string `json:"http_params"` //HTTP协议调用参数
	Mqtt_Params string `json:"mqtt_params"` //MQTT协议调用参数
}

// ToJson 转换为JSON
func (ts *TInstanceDocument) ToJson() string {
	mJ := gjson.New(ts)
	return mJ.Export()
}

// InsertCapability 增加services_capability服务能力记录
func (ts *TInstanceDocument) InsertCapability(AItem TServiceCapability) error {
	_, er := g.DB().Model("services_capability").Insert(g.Map{
		"uuid":        ts.CmdParams.Uni_Id,
		"caption":     AItem.Caption,
		"description": AItem.Description,
		"protocol":    AItem.Protocol,
		"intf_id":     AItem.Intf_id,
		"http_params": AItem.Http_Params,
		"mqtt_params": AItem.Mqtt_Params,
	})
	return er
}

// UpdateCapability 更新services_capability服务能力记录
func (ts *TInstanceDocument) UpdateCapability(AItem TServiceCapability) error {
	_, er := g.DB().Model("services_capability").Update(g.Map{
		"caption":     AItem.Caption,
		"description": AItem.Description,
		"protocol":    AItem.Protocol,
		"http_params": AItem.Http_Params,
		"mqtt_params": AItem.Mqtt_Params,
	}, "uuid=? and intf_id=?", AItem.Uni_id, AItem.Intf_id)
	return er
}

// ListCapabilitiesByUniId ListCapabilities 查询所有services_capability记录
func (ts *TInstanceDocument) ListCapabilitiesByUniId() (gdb.Result, error) {
	mRes, mEr := g.DB().Model("services_capability").Where("uuid=?", ts.CmdParams.Uni_Id).Cache(time.Second * 60).All()
	return mRes, mEr
}

// RemoveCapability 移除services_capability服务能力记录
func (ts *TInstanceDocument) RemoveCapability(AItem TServiceCapability) error {
	_, er := g.DB().Model("services_capability").Delete("uuid=? and intf_id=?", AItem.Uni_id, AItem.Intf_id)
	return er
}

// MakeResponse 处理数据返回的工作
func (ts *TInstanceDocument) MakeResponse(r *ghttp.Request, ACode int, AData g.Map) error {
	var mErr error
	switch ts.ReturnParams.Protocol {
	case "http":
		//用http协议返回
		if r == nil {
			mErr = errors.New(fmt.Sprintf("丢失HTTP对象 CMD=%s MSGID=%s", ts.Cmd, ts.MsgId))
		} else {
			switch ts.ReturnParams.Format {
			case "text":
				//返回文本
				r.Response.Write(g.Map{
					"code":   ACode,
					"data":   AData,
					"cmd":    ts.Cmd,
					"msg_id": ts.MsgId,
				})
			case "json":
				//返回JSON
				_ = r.Response.WriteJson(g.Map{
					"code":   ACode,
					"data":   AData,
					"cmd":    ts.Cmd,
					"msg_id": ts.MsgId,
				})
			}
		}
	case "mqtt":
		//用mqtt协议返回
		//构建payload
		mMap := g.Map{
			"code":   ACode,
			"data":   AData,
			"cmd":    ts.Cmd,
			"msg_id": ts.MsgId,
		}
		mJson := gjson.New(mMap)
		mPayload := mJson.Export()
		//连接MQTT服务器
		var mMQTT TMQTTComponent
		mMQTT.Host = ts.ReturnParams.Mqtt_Host
		mMQTT.Port = ts.ReturnParams.Mqtt_Port
		mMQTT.User = ts.ReturnParams.Mqtt_User
		mMQTT.Password = ts.ReturnParams.Mqtt_Pwd
		//初始化并建立连接
		_ = mMQTT.InitAndConnect()
		//发送消息
		_ = mMQTT.Publish(ts.ReturnParams.Mqtt_topic_root+"/"+ts.ReturnParams.Mqtt_topic_child, mPayload)
		//关闭连接
		mMQTT.Close()
		_ = r.Response.WriteJson(mMap)
	}
	return mErr
}

// ListServices 列出所有的服务记录
func (ts *TInstanceDocument) ListServices() (gdb.Result, error) {
	mRes, mEr := g.DB().Model("services_master").Cache(time.Second * 60).All()
	return mRes, mEr
}

// InsertMaster 插入新的服务记录
func (ts *TInstanceDocument) InsertMaster() error {
	_, er := g.DB().Model("services_master").Insert(g.Map{
		"uuid":                ts.CmdParams.Uni_Id,
		"service_name":        ts.CmdParams.ServiceName,
		"service_description": ts.CmdParams.ServiceDescription,
		"service_type":        ts.CmdParams.ServiceType,
		"http_enabled":        ts.CmdParams.Http_Enabled,
		"http_host":           ts.CmdParams.Http_Host,
		"http_port":           ts.CmdParams.Http_Port,
		"mqtt-enabled":        ts.CmdParams.Mqtt_Enabled,
		"mqtt_host":           ts.CmdParams.Mqtt_Host,
		"mqtt_port":           ts.CmdParams.Mqtt_Port,
		"mqtt_topic_root":     ts.CmdParams.Mqtt_topic_root,
		"mqtt_params":         ts.CmdParams.Mqtt_Params,
	})
	return er
}

// UpdateByUniId 根据UUID更新Master服务记录数据
func (ts *TInstanceDocument) UpdateByUniId() error {
	_, er := g.DB().Model("services_master").Update(g.Map{
		"service_name":        ts.CmdParams.ServiceName,
		"service_description": ts.CmdParams.ServiceDescription,
		"service_type":        ts.CmdParams.ServiceType,
		"http_enabled":        ts.CmdParams.Http_Enabled,
		"http_host":           ts.CmdParams.Http_Host,
		"http_port":           ts.CmdParams.Http_Port,
		"mqtt-enabled":        ts.CmdParams.Mqtt_Enabled,
		"mqtt_host":           ts.CmdParams.Mqtt_Host,
		"mqtt_port":           ts.CmdParams.Mqtt_Port,
		"mqtt_topic_root":     ts.CmdParams.Mqtt_topic_root,
		"mqtt_params":         ts.CmdParams.Mqtt_Params,
	}, "uuid=?", ts.CmdParams.Uni_Id)
	return er
}

// RemoveByUniId 根据UUID删除Master主记录数据
func (ts *TInstanceDocument) RemoveByUniId() error {
	_, er := g.DB().Model("services_master").Delete("uuid=?", ts.CmdParams.Uni_Id)
	return er
}

// TUserDocument 用户报文结构
type TUserDocument struct {
	Cmd          string                    `json:"cmd"`           //命令字（全部大写），如REG=注册新用户
	CmdParams    TUserDocumentCmdParams    `json:"cmd_params"`    //命令参数
	ReturnParams TUserDocumentReturnParams `json:"return_params"` //返回数据参数
}

type TUserDocumentCmdParams struct {
}

type TUserDocumentReturnParams struct {
}
